TerraformでCloudWatchイベントのターゲット先に「別アカウントのイベントバス」を設定してみた
こんにちは、コンサルティング部の後藤です。
先日CloudWatchイベントルールの作成をTerraformで行いました。その時、ターゲットを「別アカウントのイベントバスを指定」にする必要があったのですが、Terraformで設定する際に少し分かりにくかったので備忘録になります。
Terraformバージョン
本記事は以下のバージョンを使用して実行しています。
$ terraform --version Terraform v0.12.29 + provider.aws v3.4.0
CloudWatchイベント作成
TerraformでCloudWatchイベントを作成する場合、イベントソースとターゲットでresourceが異なります。
まず、イベントソースのみ指定したルールを作成します。今回はイベントソースとしてGuardDutyを指定しています。
resource "aws_cloudwatch_event_rule" "rule" { name = "test-rule" event_pattern = <<EOF { "source" : [ "aws.guardduty" ], "detail-type": [ "GuardDuty Finding" ] } EOF }
Terraformを実行してマネージドコンソールを確認すると、ルールが作成されていることがわかります。
CloudWatchイベントのターゲットを設定
TerraformでCloudWatchイベントのターゲットを設定する場合、resource "aws_cloudwatch_event_target"
を使用します。
ドキュメントがこちらになるのですが、ECSやKinesis、Batch等をターゲットにした設定値はあるのに対して、「別アカウントのイベントバスを指定」で使用する設定値が見当たらないので、一度手動で設定し、Terraformにimportしてどの項目を設定すれば良いか確認してみました。
ターゲット設定をTerraformにimportするためにtarget-idが必要になるため、AWS CLIで取得します。
$ aws events list-targets-by-rule --rule 【ルール名】 { "Targets": [ { "Id": "Id441716527535", # ここ! "Arn": "arn:aws:events:ap-northeast-1:123456789010:event-bus/default", "RoleArn": "arn:aws:iam::010987654321:role/service-role/AWS_Events_Invoke_Event_Bus_1500696013" } ] }
Terraform importを実行する前にresourceを以下のように定義しました。
resource "aws_cloudwatch_event_target" "target" { rule = "hoge" arn = "" }
取得したtarget-idを使用してimportを実行します。
$ terraform import aws_cloudwatch_event_target.target 【ルール名】/【target-id】 # 実行例 $ terraform import aws_cloudwatch_event_target.target test-rule/Id441716527535 aws_cloudwatch_event_target.target: Importing from ID "test-rule/Id441716527535"... aws_cloudwatch_event_target.target: Import prepared! Prepared aws_cloudwatch_event_target for import aws_cloudwatch_event_target.target: Refreshing state... [id=test-rule-Id441716527535] Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform.
import後、terraform planで不足している値を確認すると、
# aws_cloudwatch_event_target.target must be replaced -/+ resource "aws_cloudwatch_event_target" "target" { - arn = "arn:aws:events:ap-northeast-1:xxxxxxxxx:event-bus/default" -> null ~ id = "test-rule-Id441716527535" -> (known after apply) - role_arn = "arn:aws:iam::xxxxxxxxxx:role/service-role/AWS_Events_Invoke_Event_Bus_1500696013" -> null ~ rule = "test-rule" -> "hoge" # forces replacement ~ target_id = "Id441716527535" -> (known after apply) }
arn / rule / role_arn の値だけで「別アカウントのイベントバスを指定」は設定出来そうです。
上記結果を参考に、以下のようなTerraformを書いてみました。
$ cat cw_event.tf ## IAMポリシー作成 resource "aws_iam_policy" "policy" { name = "cw-test-policy" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "events:PutEvents" ], "Resource": [ "arn:aws:events:*:123456789010:event-bus/default" ] } ] } EOF } ## IAMロール作成 resource "aws_iam_role" "role" { name = "cw-test-role" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "events.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } EOF } ## IAMロールにIAMポリシーをアタッチ resource "aws_iam_role_policy_attachment" "attach" { role = aws_iam_role.role.name policy_arn = aws_iam_policy.policy.arn } ## CloudWatchイベント作成 resource "aws_cloudwatch_event_rule" "rule" { name = "test2-rule" event_pattern = <<EOF { "source" : [ "aws.guardduty" ], "detail-type": [ "GuardDuty Finding" ] } EOF } ## CloudWatchイベントのターゲット設定 resource "aws_cloudwatch_event_target" "target" { rule = aws_cloudwatch_event_rule.rule.name arn = "arn:aws:events:ap-northeast-1:662149051709:event-bus/default" role_arn = aws_iam_role.role.arn }
AWSマネージドコンソールでターゲットを設定すると自動でIAMロールを作成、設定してくれますが、Terraformでターゲットを設定する場合はIAMロールを作成してあげる必要がありました。
上記Terraformを実行してAWSマネージドコンソールを確認してみると、「別のAWSアカウントのイベントバス」でターゲットが設定されたCloudWatchイベントが作成されていました。
まとめ
TerraformでCloudWatchイベントの作成、ターゲットに「別のAWSアカウントのイベントバス」を指定する方法を紹介しました。かなり小ネタなTipsになりましたが、どなたかのお役に立てば幸いです。